package org.jackysoft.service.impl;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jackysoft.entity.AcegiRole;
import org.jackysoft.entity.TreeNode;
import org.jackysoft.entity.User;
import org.jackysoft.google.collection.TreeNodeZtreeFunction;
import org.jackysoft.google.collection.ZTreeNode;
import org.jackysoft.service.AbstractIdentifiedService;
import org.jackysoft.service.TreeNodeService;
import org.jackysoft.util.SpringSecurityUtils;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

@Service
@Transactional
public class TreeNodeServiceImpl 
extends AbstractIdentifiedService<TreeNode>
implements TreeNodeService {

	/**
	 * 
	 */
	private static final long serialVersionUID = 7568888199425706132L;
	
    public TreeNodeServiceImpl() {
		this.type = TreeNode.class;
	}

	
	@Override
	@SuppressWarnings("unchecked")
	public Collection<TreeNode> getChildrenLogined(String id) {
		
		
		
		User cu = SpringSecurityUtils.getCurrentUser();
		Collection<AcegiRole> auths = cu.getAuthoritys();
		if(CollectionUtils.isEmpty(auths)) return Collections.EMPTY_LIST;
		Collection<String> acegiRoles = Lists.newArrayList();
		for(AcegiRole ar:auths) {
			if(ar==null)continue;
			acegiRoles.add(ar.getId());
		}
		
		Map<String,Object> parameter = Maps.newHashMap();
		parameter.put("nodeId", id);
		parameter.put("acegiIds", acegiRoles);
		List<TreeNode> list = this.sqlSession.selectList("getChildrenLogined", parameter);	
		return list;

	}

	/**
	 * 返回所有资源,用于权限分配
	 * */
	@Override
	public Collection<TreeNode> getChildren(String id)
			throws DataAccessException {
	
		List<TreeNode> list = this.sqlSession.selectList("getChilren", id);	
		return list;
	}

	/**
	 * 获得当前用户权限所分配的树节点
	 * 
	 * @param parentId
	 *            父ID
	 * @param acegi
	 *            角色编号
	 * @param htpsession
	 *            HttpSession
	 * @return Collection<TreeNode> 符合树节点集合
	 * */
	@Override
	public Collection<TreeNode> getChildren(String id,String acegi) 
			throws DataAccessException {
		
		Map<String,Object> parameter = Maps.newHashMap();
		parameter.put("nodeId", id);
		parameter.put("acegiId", acegi);
		List<TreeNode> list = this.sqlSession.selectList("getChilrenByAcegi", parameter);	
		return list;
	}

	@Override
	public void create(TreeNode t) throws DataAccessException {
		String sqlId =!t.isChild()?"addToParent":"addToLeaf";
		this.sqlSession.insert(sqlId, t);
	}

	
	@Override
	public void remove(TreeNode t) throws DataAccessException {
		if(t.isLeaf()){
			this.sqlSession.delete("deleteLeaf", t.getId());		
			
		}else{
			Collection<TreeNode> nodes = this.getAllChildren(t.getId());
		    this.sqlSession.delete("deleteTARelatioin", nodes);
		    this.sqlSession.delete("deleteParent",t.getId());
		}
		
	}
		
	@Override
	public void update(TreeNode t) throws DataAccessException {
		  this.sqlSession.update("updateNode", t);

	}

	@Override
	public void saveSorted(Collection<TreeNode> trees)
			throws DataAccessException {
		assert trees != null : "参数错误";
		for (TreeNode t : trees) {
			this.sqlSession.update("updateSorts", t);
		}

	}


	/**
	 * 取得某个权限的所有资源编号
	 * */
	@Override
	public Collection<TreeNode> getChildren(AcegiRole secRole)
			throws DataAccessException {
		if(secRole==null) return Collections.emptyList();
		List<TreeNode> alist = this.sqlSession.selectList("getsByAcegi", secRole.getId());
		return alist;
	}

	@Override
	public Collection<ZTreeNode> ztree(TreeNode bean)
			throws DataAccessException {
		if(bean==null){
			bean= new TreeNode();
			bean.setId("root");
		}
		Collection<TreeNode> trees = this.getChildrenLogined(bean.getId());
		return Collections2.transform(trees,new TreeNodeZtreeFunction());
	}


	@Override
	public TreeNode[] getPath(String id) {
		
		List<TreeNode> nodes = this.sqlSession.selectList("getPath", id);
		return nodes.toArray(new TreeNode[0]);
	}


	@Override
	public int getDepth(String id) {
		
		TreeNode tn = this.sqlSession.selectOne("getDepth", id);
		return tn.getDepth();
	}


	@Override
	public TreeNode[] getChildDepths(String id) {
		List<TreeNode> nodes = this.sqlSession.selectList("getChildDepths", id);
		return nodes.toArray(new TreeNode[0]);
	}


	@Override
	public Collection<TreeNode> getAllChildren(String id) {
		List<TreeNode> nodes = this.sqlSession.selectList("getAllChildren", id);
		return nodes;
	}


	@Override
	public TreeNode get(final int lft, final int rgt) {
		TreeNode node = this.sqlSession.selectOne("getBylr", new HashMap<String,Object>(){
			/**
			 * 
			 */
			private static final long serialVersionUID = 1L;

			{
				put("lft",lft);
				put("rgt",rgt);
			}
		});
		return node;
	}


	@Override
	public void create(Collection<TreeNode> bs) throws DataAccessException {
		 for(TreeNode tn :bs){
			this.create(tn);
		 }
	}
	

	
	
}